﻿using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.IO;
using System.Text;
using System.Web;
using System.Xml;
using shfa.snomtastic.data.business;
using shfa.snomtastic.data.security;
using shfa.snomtastic.data;

namespace shfa.snomtastic.web
{
    public partial class settings : System.Web.UI.Page
    {
        public string host { get; set; }
        public string appPath { get; set; }
        public string macAddress { get; set; }
        public string ipAddress { get; set; }
        public string userAgent { get; set; }
        public string userName { get; set; }
        public string userPassword { get; set; }
        public bool isPhone { get; set; }
        public DirectoryEntry adUser { get; set; }
        public UserInfo dbUser { get; set; }
        public PhoneInfo Phone { get; set; }
        public AppConfig ac = new AppConfig();

        public enum PhoneFailMode { Success, ErrorOn, ErrorOff };


        protected void Page_Load(object sender, EventArgs e)
        {
            macAddress = Request.QueryString["mac"];
            host = Request.Url.Authority;
            if (HttpRuntime.AppDomainAppVirtualPath != "/")
                appPath = host + HttpRuntime.AppDomainAppVirtualPath;
            else
                appPath = host;
            ipAddress = Request.UserHostAddress;

            Phone = GetPhoneInfo();
            if (Phone != null && Phone.UserId != Guid.Empty)
                SetUserInfo(Phone.UserId);


            userAgent = Request.ServerVariables["HTTP_USER_AGENT"];

        }

        protected void Page_PreRender(object sender, EventArgs e)
        {

            Response.ContentType = "text/xml";
            Response.ContentEncoding = Encoding.UTF8;

            Guid phoneId = new Guid();
            Guid userId = new Guid();

            if (Phone != null)
            {
                phoneId = Phone.PhoneId;
                userId = Phone.UserId;
            }

            EventLog el = new EventLog();



            using (TextWriter textWriter = new StreamWriter(Response.OutputStream, Encoding.UTF8))
            {

                XmlWriterSettings writerSettings = new XmlWriterSettings();
                writerSettings.OmitXmlDeclaration = false;
                writerSettings.CloseOutput = true;

                XmlWriter xmlWriter = XmlTextWriter.Create(textWriter, writerSettings);

                //Write the settings
                xmlWriter.WriteStartElement("phone-settings");

                // Global Settings
                WriteGlobal(ref xmlWriter);

                // Specific Settings
                string FailMessage;
                string ErrorType;
                //bool bWriteFailedConfig;
                PhoneFailMode pf = PhoneFail(out FailMessage, out ErrorType);
                switch (pf)
                {
                    case PhoneFailMode.Success:
                        WriteSettings(ref xmlWriter);
                        el.LogEvent(phoneId, userId, macAddress, ipAddress, userAgent, "Phone", "Settings requested by phone.", "Information");
                        break;
                    case PhoneFailMode.ErrorOn:
                        WriteFailed(ref xmlWriter);
                        el.LogEvent(phoneId, userId, macAddress, ipAddress, userAgent, "Phone", "Settings Error: (" + FailMessage + ")", ErrorType);
                        break;
                    case PhoneFailMode.ErrorOff:
                        el.LogEvent(phoneId, userId, macAddress, ipAddress, userAgent, "Phone", "Settings Error: (" + FailMessage + ")", ErrorType);
                        break;
                    default:
                        break;
                }



                xmlWriter.WriteEndElement();
                xmlWriter.Close();




            }

        }



        #region Settings

        private void WriteGlobal(ref XmlWriter w)
        {
            w.WriteStartElement("action_reg_failed");
            w.WriteAttributeString("perm", "&");
            w.WriteValue(ac.Items["siteRoot"] + "phone/actions.aspx?action=reg_failed&mac=" + macAddress);
            w.WriteEndElement();

            w.WriteStartElement("action_log_on_url");
            w.WriteAttributeString("perm", "&");
            w.WriteValue(ac.Items["siteRoot"] + "phone/actions.aspx?action=log_on&mac=" + macAddress);
            w.WriteEndElement();

            w.WriteStartElement("firmware_status");
            w.WriteAttributeString("perm", "");
            w.WriteValue(ac.Items["siteRoot"] + "phone/firmware.aspx?mac=" + macAddress);
            w.WriteEndElement();

            w.WriteStartElement("firmware_interval");
            w.WriteAttributeString("perm", "");
            w.WriteValue("5");
            w.WriteEndElement();

            w.WriteStartElement("setting_server");
            w.WriteAttributeString("perm", "");
            w.WriteValue(ac.Items["siteRoot"] + "phone/phone.aspx?mac={mac}");
            w.WriteEndElement();

        }

        private void WriteSettings(ref XmlWriter w)
        {
            ConfigurationSettingController csc = new ConfigurationSettingController();
            List<ConfigurationSettingInfo> csiList = csc.GetConfigurationSettingsForPhone(macAddress);
            SettingController sc = new SettingController();

            // Added 2-6-2010 (user_active should not need to be set in specific configurations)
            w.WriteStartElement("user_active");
            w.WriteAttributeString("perm", "");
            w.WriteAttributeString("idx", "1");
            w.WriteValue("on");
            w.WriteEndElement();

            if (csiList != null)
            {

                foreach (ConfigurationSettingInfo csi in csiList)
                {
                    if (csi.Active)
                    {
                        SettingInfo si = sc.SelectSetting(csi.SettingId);
                        if (si != null)
                        {
                            csi.FillDetails();
                            w.WriteStartElement(csi.Setting);
                            w.WriteAttributeString("config", csi.Config);
                            w.WriteAttributeString("source", csi.Source);
                            w.WriteAttributeString("perm", csi.PermissionFlag);
                            if (csi.SettingIndex > 0)
                                w.WriteAttributeString("idx", csi.SettingIndex.ToString());
                            w.WriteValue(shfa.snomtastic.data.common.GetFormattedValue(csi, dbUser, adUser, macAddress, ipAddress, si.Encrypted, true));
                            w.WriteEndElement();
                        }
                    }
                }
            }
        }


        private void WriteFailed(ref XmlWriter w)
        {
            string ErrorMessage = "ERROR";

            if (Phone != null && Phone.UserId != Guid.Empty && Phone.ModelId != Guid.Empty)
            {
                ModelController mc = new ModelController();
                ModelInfo mi = mc.SelectModel(Phone.ModelId);
                if (mi != null)
                {
                    ErrorMessage = mi.ErrorMessage;
                }
            }

            w.WriteStartElement("user_idle_text");
            w.WriteAttributeString("perm", "");
            w.WriteAttributeString("idx", "1");
            w.WriteValue(ErrorMessage);
            w.WriteEndElement();

            w.WriteStartElement("user_active");
            w.WriteAttributeString("perm", "");
            w.WriteAttributeString("idx", "1");
            w.WriteValue("off");
            w.WriteEndElement();

            w.WriteStartElement("settings_refresh_timer");
            w.WriteAttributeString("perm", "");
            w.WriteValue(ac.Items["failModeDelay"]);
            w.WriteEndElement();


        }

        #endregion

        #region helpers

        private PhoneFailMode PhoneFail(out string FailMessage, out string ErrorType)
        {
            ErrorType = "Error";


            if (Phone == null)
            {
                FailMessage = "Phone not registered.";
                return PhoneFailMode.ErrorOn;
            }

            if (dbUser == null)
            {
                FailMessage = "No user assigned to phone.";
                ErrorType = "Information";
                return (ac.GetItemValue("enableErrorMode").ToLower() == "true") ? PhoneFailMode.ErrorOn : PhoneFailMode.ErrorOff;

            }

            if (dbUser.LastAccessDate == null | dbUser.Password == string.Empty)
            {
                FailMessage = "Password is not set.";
                return PhoneFailMode.ErrorOn;
            }


            if (Phone != null)
            {
                if (Phone.RegistrationFailed)
                {
                    FailMessage = "Registration failed.";
                    return PhoneFailMode.ErrorOn;
                }
                else
                {
                    FailMessage = "";
                    return PhoneFailMode.Success;
                }
            }


            FailMessage = "UNKNOWN HARD ERROR !!!!!!";
            return PhoneFailMode.ErrorOn;

        }

        private PhoneInfo GetPhoneInfo()
        {
            PhoneController pc = new PhoneController();
            PhoneInfo pi = pc.SelectPhoneByMacAddress(macAddress);

            if (pi != null)
            {
                return pi;
            }
            return null;
        }


        private void SetUserInfo(Guid userId)
        {

            if (userId != Guid.Empty)
            {
                UserController uc = new UserController();
                dbUser = uc.SelectUser(userId);
                if (dbUser != null)
                {
                    adUser = GetADUser(dbUser.UserName);
                    if (adUser != null)
                    {
                        dbUser.PasswordUpdateAD = common.GetDateFromLargeInteger(adUser.Properties["pwdLastSet"][0]);
                        uc.UpdateUser(dbUser);
                    }
                }
            }
        }

        private DirectoryEntry GetADUser(string upn)
        {
            adSecurity ad = new adSecurity();
            if (upn != string.Empty)
            {
                DirectoryEntry de = ad.GetUserByUPN(upn);
                if (de != null)
                    return de;
            }

            return null;
        }


        #endregion
    }
}
